
<!DOCTYPE HTML>
<html lang="zh-hans" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>通用服务 · Cup Documentation</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="Guannan Ma">
        
        
    
    <link rel="stylesheet" href="../../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-splitter/splitter.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-anchors/plugin.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-insert-logo/plugin.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="GeneralService.html" />
    
    
    <link rel="prev" href="CommonUserSenario.html" />
    

    <style>
    @media only screen and (max-width: 640px) {
        .book-header .hidden-mobile {
            display: none;
        }
    }
    </style>
    <script>
        window["gitbook-plugin-github-buttons"] = {"repo":"baidu/CUP","types":["star","watch","fork"],"size":"large"};
    </script>

    
        <link rel="shortcut icon" href='../images/cup.logo.jpg' type="image/x-icon">
    
    
        <link rel="bookmark" href='../images/cup.logo.jpg' type="image/x-icon">
    
    
        <link rel="apple-touch-icon" href='../images/cup.logo.jpg'>
    
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="输入并搜索" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    
    
        
        <li>
            <a href="https://github.com/baidu/CUP" target="_blank" class="custom-link">Github Website</a>
        </li>
    
    

    
    <li class="divider"></li>
    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    CUP概述
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" >
            
                <span>
            
                    
                    用户案例
            
                </span>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.2.1" data-path="CommonUserSenario.html">
            
                <a href="CommonUserSenario.html">
            
                    
                    基础功能
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="1.2.2" data-path="CommonService.html">
            
                <a href="CommonService.html">
            
                    
                    通用服务
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.3" data-path="GeneralService.html">
            
                <a href="GeneralService.html">
            
                    
                    快速构建PythonService
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.4" data-path="AsyncNet.html">
            
                <a href="AsyncNet.html">
            
                    
                    异步网络通讯协议
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.3" >
            
                <a target="_blank" href="https://cup.iobusy.com/api-ref/">
            
                    
                    官方文档
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="../CommitCode.html">
            
                <a href="../CommitCode.html">
            
                    
                    参与社区
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5" data-path="../DevMembers.html">
            
                <a href="../DevMembers.html">
            
                    
                    开发人员
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6" >
            
                <span>
            
                    
                    开发计划
            
                </span>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1" data-path="../RoadMap.html">
            
                <a href="../RoadMap.html">
            
                    
                    RoadMap
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2" data-path="../ChangeLog.html">
            
                <a href="../ChangeLog.html">
            
                    
                    ReleaseNote
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            本书使用 GitBook 发布
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >通用服务</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <!-- MDTOC maxdepth:6 firsth1:1 numbering:0 flatten:0 bullets:1 updateOnSave:1 -->
<ul>
<li><a href="#1-&#x901A;&#x7528;service">1. &#x901A;&#x7528;Service</a>   <ul>
<li><a href="#11-threadthreadpool-&#x7EBF;&#x7A0B;&#x6C60;">1.1 Thread/Threadpool &#x7EBF;&#x7A0B;&#x6C60;</a>   </li>
<li><a href="#12-interruptible-thread-&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;-&#x8BFB;&#x5199;&#x9501;rwlock">1.2 Interruptible Thread &#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B; / &#x8BFB;&#x5199;&#x9501;RWLock</a>   </li>
<li><a href="#13-&#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;-&#x6267;&#x884C;&#x5668;">1.3 &#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;, &#x6267;&#x884C;&#x5668;</a>   </li>
<li><a href="#14-autowaits-&#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;">1.4 Autowaits &#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;</a>   </li>
<li><a href="#15-bufferpool-&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;">1.5 BufferPool &#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;</a>   </li>
<li><a href="#16-generator">1.6 Generator &#x751F;&#x6210;&#x5668;</a>   </li>
<li><a href="#17-serializer-meta&#x6301;&#x4E45;&#x5316;">1.7 Serializer Meta&#x6301;&#x4E45;&#x5316;</a>   </li>
<li><a href="#18-heartbeat-&#x5FC3;&#x8DF3;&#x670D;&#x52A1;">1.8 HeartBeat &#x5FC3;&#x8DF3;&#x670D;&#x52A1;</a>   </li>
</ul>
</li>
</ul>
<!-- /MDTOC -->
<h1 id="1-&#x901A;&#x7528;service"><a name="1-&#x901A;&#x7528;service" class="plugin-anchor" href="#1-&#x901A;&#x7528;service"><i class="fa fa-link" aria-hidden="true"></i></a>1. &#x901A;&#x7528;Service</h1>
<h2 id="11-threadthreadpool-&#x7EBF;&#x7A0B;&#x6C60;"><a name="11-threadthreadpool-&#x7EBF;&#x7A0B;&#x6C60;" class="plugin-anchor" href="#11-threadthreadpool-&#x7EBF;&#x7A0B;&#x6C60;"><i class="fa fa-link" aria-hidden="true"></i></a>1.1 Thread/Threadpool &#x7EBF;&#x7A0B;&#x6C60;</h2>
<p><code>cup.services.threadpool</code>&#x652F;&#x6301;&#x4E30;&#x5BCC;&#x7684;&#x7EBF;&#x7A0B;&#x6C60;&#x573A;&#x666F;, &#x53EF;&#x4EE5;:</p>
<ul>
<li>&#x5178;&#x578B;&#x7684;&#x4F5C;&#x4E1A;&#x6A21;&#x578B;</li>
<li>&#x652F;&#x6301;&#x6267;&#x884C;&#x540E;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x5904;&#x7406;</li>
<li>&#x652F;&#x6301;&#x70ED;&#x8C03;&#x6574;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;&#x6570;</li>
<li>&#x652F;&#x6301;&#x963B;&#x585E;(stop)/&#x975E;&#x963B;&#x585E;(try_stop)&#x505C;&#x6B62;&#x65B9;&#x5F0F;</li>
</ul>
<pre><code class="lang-python"><span class="hljs-comment"># &#x4EE5;&#x4F7F;&#x7528;&#x7EBF;&#x7A0B;&#x6C60;&#x591A;&#x7EBF;&#x7A0B;scp&#x5206;&#x53D1;&#x6587;&#x4EF6;&#x4E3A;&#x4F8B;</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CRemote</span><span class="hljs-params">(object)</span>:</span>
    <span class="hljs-string">&quot;&quot;&quot;
    handle remote things
    &quot;&quot;&quot;</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, username, password, retry=<span class="hljs-number">0</span>)</span>:</span>
        self._username =  username
        self._passwd = password
        self._wget_retry = retry
        self._thdpool = threadpool.ThreadPool(minthreads=<span class="hljs-number">2</span>, maxthreads=<span class="hljs-number">4</span>)
        self._generator = generator.CGeneratorMan()

    <span class="hljs-comment"># pylint: disable=R0913</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_thread_scp_dir_by_tarfile</span><span class="hljs-params">(self,
            hostname, dst, tarpath, ret_list, timeout
        )</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;
        do sth in a thread&#x3002; &#x6267;&#x884C;&#x8BE5;scp&#x547D;&#x4EE4;&#x7684;&#x5B9E;&#x9645;&#x7EBF;&#x7A0B;. &#x6267;&#x884C;scp
        &quot;&quot;&quot;</span>
        <span class="hljs-keyword">if</span> os.path.normpath(dst) == <span class="hljs-string">&apos;/&apos;</span>:
            <span class="hljs-keyword">raise</span> IOError(<span class="hljs-string">&apos;You CANNOT delete root /&apos;</span>)
        tarfile_name = os.path.basename(tarpath)
        log.info(<span class="hljs-string">&apos;to mkdir in case it does not exists:{0}&apos;</span>.format(dst))
        cmd = <span class="hljs-string">&apos;mkdir -p {0};&apos;</span>.format(dst, dst)
        ret = self.remote(hostname, cmd, <span class="hljs-number">10</span>)
        ret[<span class="hljs-string">&apos;hostname&apos;</span>] = hostname
        <span class="hljs-keyword">if</span> ret[<span class="hljs-string">&apos;exitstatus&apos;</span>] != <span class="hljs-number">0</span> <span class="hljs-keyword">or</span> ret[<span class="hljs-string">&apos;remote_exitstatus&apos;</span>] != <span class="hljs-number">0</span>:
            log.critical(<span class="hljs-string">&apos;mkdir dst failed, error info:{0}&apos;</span>.format(ret))
            ret_list.append(ret)
            <span class="hljs-keyword">return</span>
        log.info(<span class="hljs-string">&apos;scp_dir_by_tarfile, src tarfile:{0} dst:{1}&apos;</span>.format(
            tarpath, dst)
        )
        ret = self.lscp(tarpath, hostname, dst)
        ret[<span class="hljs-string">&apos;hostname&apos;</span>] = hostname
        <span class="hljs-keyword">if</span> ret[<span class="hljs-string">&apos;exitstatus&apos;</span>] != <span class="hljs-number">0</span> <span class="hljs-keyword">or</span> ret[<span class="hljs-string">&apos;remote_exitstatus&apos;</span>] != <span class="hljs-number">0</span>:
            log.critical(<span class="hljs-string">&apos;lscp failed, error info:{0}&apos;</span>.format(ret))
            ret_list.append(ret)
        <span class="hljs-keyword">else</span>:
            cmd = <span class="hljs-string">&apos;cd {0}; tar zxf {1}; rm -f {2}&apos;</span>.format(
                dst, tarfile_name, tarfile_name
            )
            ret = self.remote(hostname, cmd, timeout=timeout)
            ret[<span class="hljs-string">&apos;hostname&apos;</span>] = hostname
            ret_list.append(ret)
            log.info(<span class="hljs-string">&apos;succeed to scp dir, hostname:{0}&apos;</span>.format(hostname))
        <span class="hljs-keyword">return</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">scp_hosts_dir_by_tarfile</span><span class="hljs-params">(self,
        src, hosts, dst, tempfolder, tarfile_name=None, timeout=<span class="hljs-number">600</span>
    )</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;
        scp a folder to multiple hosts
        &#x4F7F;&#x7528;&#x7EBF;&#x7A0B;&#x6C60;&#xFF0C;&#x591A;&#x7EBF;&#x7A0B;&#x5E76;&#x53D1;&#x7684;scp&#x62F7;&#x8D1D;&#x672C;&#x5730;&#x76EE;&#x5F55;&#x5230;&#x8FDC;&#x7A0B;&#x673A;&#x5668;&#x76EE;&#x5F55;

        :hosts:
            hosts that will be scped
        :tempfolder:
            temp folder which will store tar file temporarily.
        &quot;&quot;&quot;</span>
        src = os.path.normpath(src)
        <span class="hljs-keyword">if</span> tarfile_name <span class="hljs-keyword">is</span> <span class="hljs-keyword">None</span>:
            tarfile_name = <span class="hljs-string">&apos;{0}.{1}.tar.gz&apos;</span>.format(
                net.get_local_hostname(), time.time()
            )
        src_folder_name = os.path.basename(src)
        name = <span class="hljs-string">&apos;{0}/{1}&apos;</span>.format(tempfolder, tarfile_name)
        log.info(<span class="hljs-string">&apos;to compress folder into tarfile:{0}&apos;</span>.format(name))
        <span class="hljs-keyword">with</span> tarfile.open(tempfolder + <span class="hljs-string">&apos;/&apos;</span> + tarfile_name, <span class="hljs-string">&apos;w:gz&apos;</span>) <span class="hljs-keyword">as</span> tar:
            tar.add(src, src_folder_name)

        ret_list = []
        <span class="hljs-comment"># &#x542F;&#x52A8;&#x7EBF;&#x7A0B;&#x6C60;</span>
        self._thdpool.start()
        <span class="hljs-keyword">for</span> hostname <span class="hljs-keyword">in</span> hosts:
            <span class="hljs-comment"># &#x50CF;&#x7EBF;&#x7A0B;&#x6C60;&#x6254;&#x4F5C;&#x4E1A;</span>
            self._thdpool.add_1job(
                self._thread_scp_dir_by_tarfile,
                hostname,
                dst,
                name,
                ret_list,
                timeout
            )
        time.sleep(<span class="hljs-number">2</span>)
        <span class="hljs-comment"># &#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x7B49;&#x5F85;&#x7EBF;&#x7A0B;&#x6C60;&#x5173;&#x95ED;</span>
        self._thdpool.stop()  <span class="hljs-comment"># &#x6CE8;&#x610F;&#xFF0C;&#x7EBF;&#x7A0B;&#x6C60;&#x4E5F;&#x63D0;&#x4F9B;try_stop&#x63A5;&#x53E3;&#xFF0C;&#x5177;&#x4F53;&#x53EF;&#x4EE5;&#x770B;&#x6587;&#x6863;</span>
        <span class="hljs-comment"># if not ret:</span>
        <span class="hljs-comment">#     errmsg = &apos;failed to stop threadpool while dispath files&apos;</span>
        <span class="hljs-comment">#     content = errmsg</span>
        <span class="hljs-comment">#     petaqa.peta.lib.common.send_mail(errmsg, content)</span>
        <span class="hljs-comment">#     log.error(errmsg)</span>
        <span class="hljs-comment">#     log.error(content)</span>
        os.unlink(name)
        <span class="hljs-keyword">return</span> ret_list
</code></pre>
<h2 id="12-interruptible-thread-&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;--&#x8BFB;&#x5199;&#x9501;rwlock"><a name="12-interruptible-thread-&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;--&#x8BFB;&#x5199;&#x9501;rwlock" class="plugin-anchor" href="#12-interruptible-thread-&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;--&#x8BFB;&#x5199;&#x9501;rwlock"><i class="fa fa-link" aria-hidden="true"></i></a>1.2 Interruptible Thread &#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B; / &#x8BFB;&#x5199;&#x9501;RWLock</h2>
<p>python&#x539F;&#x751F;&#x7EBF;&#x7A0B;&#x5B9E;&#x73B0;, &#x5728;&#x8FD0;&#x884C;&#x8FC7;&#x7A0B;&#x4E2D;&#x65E0;&#x6CD5;&#x8FDB;&#x884C;&#x5E72;&#x6D89;. &#x8FD9;&#x5BF9;&#x4E8E;&#x5B9E;&#x65F6;&#x5904;&#x7406;&#x4EFB;&#x52A1;&#x4E2D;&#x9700;&#x8981;&#x7ACB;&#x523B;&#x505C;&#x6B62;&#x7684;&#x573A;&#x666F;&#x4E0D;&#x9002;&#x7528;.
<code>cup.thread</code>&#x63D0;&#x4F9B;&#x4E86;&#x4E24;&#x7C7B;&#x670D;&#x52A1;</p>
<blockquote>
<ul>
<li>&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;CupThread</li>
<li>RWLock &#x8BFB;&#x5199;&#x9501;</li>
</ul>
</blockquote>
<p>&#x53EF;&#x6253;&#x65AD;&#x7EBF;&#x7A0B;&#x7EE7;&#x627F;&#x81EA;threading.Thread, &#x9664;&#x4E86;&#x539F;&#x751F;&#x7684;&#x51FD;&#x6570;&#x5916;&#x62E5;&#x6709;&#x4E09;&#x4E2A;&#x65B0;&#x7279;&#x6027;:</p>
<ol>
<li>raise_exc, &#x50CF;&#x7EBF;&#x7A0B;&#x53D1;&#x9001;exception&#x5E76;&#x6253;&#x65AD;&#x5979;&#x7684;&#x6267;&#x884C;&#x72B6;&#x6001;, to send a raise-exception signal to the thread,
 TRY to let the thread raise an exception.</li>
<li>get_my_tid, get thread id</li>
<li>terminate, &#x505C;&#x6B62;&#x8BE5;&#x7EBF;&#x7A0B;, &#x62E5;&#x6709;&#x91CD;&#x8BD5;&#x673A;&#x5236;</li>
</ol>
<p>&#x8BFB;&#x5199;&#x9501;&#x793A;&#x4F8B;:</p>
<pre><code class="lang-python"><span class="hljs-comment"># &#x8BFB;&#x5199;&#x9501;&#x652F;&#x6301;</span>
<span class="hljs-comment"># for RWLock unittest</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_rw_rw_lock</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># &#x5199;&#x9501;&#x6709;&#x4E14;&#x4EC5;&#x6709;&#x4E00;&#x4E2A;&#x88AB;&#x83B7;&#x53D6;</span>
    lock = thread.RWLock()
    lock.acquire_writelock(<span class="hljs-keyword">None</span>)
    <span class="hljs-keyword">try</span>:
        lock.acquire_writelock(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">except</span> RuntimeError <span class="hljs-keyword">as</span> error:
        <span class="hljs-keyword">pass</span>
    <span class="hljs-keyword">try</span>:
        lock.acquire_readlock(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">except</span> RuntimeError <span class="hljs-keyword">as</span> error:
        <span class="hljs-keyword">pass</span>
    lock.release_writelock()


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_rd_rw_lock</span><span class="hljs-params">()</span>:</span>
    lock = thread.RWLock()
    <span class="hljs-comment"># 1. &#x5148;&#x83B7;&#x53D6;&#x8BFB;&#x9501;, &#x8BFB;&#x9501;&#x5728;&#x6CA1;&#x6709;&#x5199;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x53EF;&#x4EE5;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x83B7;&#x53D6;</span>
    lock.acquire_readlock(<span class="hljs-keyword">None</span>)   <span class="hljs-comment"># None means wait until get the lock</span>
    lock.acquire_readlock(wait_time=<span class="hljs-number">1</span>)  <span class="hljs-comment"># will return if timeouts without the lock</span>
    lock.acquire_readlock(<span class="hljs-number">2</span>)

    <span class="hljs-comment"># 2. &#x6B64;&#x65F6;&#x83B7;&#x53D6;&#x5199;&#x9501;&#x4F1A;&#x5931;&#x8D25;, &#x629B;&#x51FA;RuntimeError&#x5F02;&#x5E38;</span>
    <span class="hljs-keyword">try</span>:
        lock.acquire_writelock(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">except</span> RuntimeError <span class="hljs-keyword">as</span> error:
        <span class="hljs-keyword">pass</span>
    <span class="hljs-comment"># 3. &#x91CA;&#x653E;&#x6240;&#x6709;&#x8BFB;&#x9501;</span>
    lock.release_readlock()
    lock.release_readlock()
    lock.release_readlock()
    <span class="hljs-comment"># 4. &#x83B7;&#x53D6;&#x5199;&#x9501;, &#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x53EF;&#x4EE5;&#x83B7;&#x53D6;&#x6210;&#x529F;</span>
    <span class="hljs-keyword">try</span>:
        lock.acquire_writelock(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">except</span> RuntimeError <span class="hljs-keyword">as</span> error:
        <span class="hljs-keyword">assert</span> <span class="hljs-keyword">False</span>
    lock.release_writelock()
</code></pre>
<h2 id="13-&#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;-&#x6267;&#x884C;&#x5668;"><a name="13-&#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;-&#x6267;&#x884C;&#x5668;" class="plugin-anchor" href="#13-&#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;-&#x6267;&#x884C;&#x5668;"><i class="fa fa-link" aria-hidden="true"></i></a>1.3 &#x7EBF;&#x7A0B;&#x6C60;&#x7684;&#x884D;&#x751F;&#x7269;, &#x6267;&#x884C;&#x5668;</h2>
<p>cup.services.executor, &#x7EBF;&#x7A0B;&#x6C60; based &#x6267;&#x884C;&#x5668;, &#x652F;&#x6301;:</p>
<ul>
<li>delay_exec &#x5EF6;&#x8FDF;xx&#x79D2;&#x6267;&#x884C;</li>
<li>queue_exec &#x6392;&#x961F;&#x6267;&#x884C;<ul>
<li><code>def delay_exec(self,delay_time_insec, function, urgency, *args, **kwargs)</code></li>
</ul>
</li>
</ul>
<p>&#x5EF6;&#x8FDF;&#x6267;&#x884C;&#x4EE3;&#x7801;&#x793A;&#x4F8B;:</p>
<pre><code class="lang-python"><span class="hljs-comment"># &#x8C01;&#x6CA1;&#x6709;&#x5EF6;&#x8FDF;&#x4E2A;XX&#x79D2;&#xFF0C;&#x6216;&#x8005;&#x5468;&#x671F;&#x6027;XX&#x79D2;&#x540E;&#x6267;&#x884C;&#x67D0;&#x4EF6;&#x4E8B;&#x60C5;&#x7684;&#x9700;&#x6C42;&#x5462;?</span>

<span class="hljs-keyword">from</span> cup <span class="hljs-keyword">import</span> log
<span class="hljs-keyword">from</span> cup.services <span class="hljs-keyword">import</span> executor

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestMyCase</span><span class="hljs-params">(unittest.CUTCase)</span>:</span>
    <span class="hljs-string">&quot;&quot;&quot;
    test class for cup
    &quot;&quot;&quot;</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
        super(self.__class__, self).__init__(
            <span class="hljs-string">&apos;./test.log&apos;</span>, log.DEBUG
        )
        log.info(<span class="hljs-string">&apos;Start to run &apos;</span> + str(__file__))
        self._executor = executor.ExecutionService(
        )

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setup</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;
        setup
        &quot;&quot;&quot;</span>
        self._executor.run()
        self._info = time.time()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_change_data</span><span class="hljs-params">(self, data=None)</span>:</span>
        self._info = time.time() + <span class="hljs-number">100</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_run</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;
        @author: maguannan
        &quot;&quot;&quot;</span>
        self._executor.delay_exec(<span class="hljs-number">5</span>, self._change_data, <span class="hljs-number">1</span>)  <span class="hljs-comment"># &#x5EF6;&#x8FDF;5&#x79D2;&#x6267;&#x884C;&#x67D0;&#x4E2A;&#x51FD;&#x6570;&#xFF0C; &#x540C;&#x65F6;&#x652F;&#x6301;&#x51FD;&#x6570;&#x53C2;&#x6570;&#x4F20;&#x9012;</span>
        time.sleep(<span class="hljs-number">2</span>)
        <span class="hljs-keyword">assert</span> time.time() &gt; self._info
        time.sleep(<span class="hljs-number">5</span>)
        <span class="hljs-keyword">assert</span> time.time() &lt; self._info

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">teardown</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;
        teardown
        &quot;&quot;&quot;</span>
        cup.log.info(<span class="hljs-string">&apos;End running &apos;</span> + str(__file__))
        self._executor.stop()

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&apos;__main__&apos;</span>:
    cup.unittest.CCaseExecutor().runcase(TestMyCase())
</code></pre>
<h2 id="14-autowaits-&#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;"><a name="14-autowaits-&#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;" class="plugin-anchor" href="#14-autowaits-&#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;"><i class="fa fa-link" aria-hidden="true"></i></a>1.4 Autowaits &#x4E8B;&#x4EF6;&#x9A71;&#x52A8;&#x7B49;&#x5F85;</h2>
<pre><code class="lang-python">
<span class="hljs-comment"># &#x7B49;&#x5F85;&#x67D0;&#x4E2A;&#x6761;&#x4EF6;&#x8FBE;&#x6210;&#x5426;&#x5219;&#x963B;&#x585E;&#x76F4;&#x5230;&#x8D85;&#x65F6;&#x3002; &#xFF08;&#x518D;&#x4E5F;&#x4E0D;&#x7528;while for&#x5FAA;&#x73AF;sleep&#x554A; &#x4EB2;&#x4EEC;&#xFF09;</span>

<span class="hljs-comment"># &#x7B49;&#x5F85;&#x6587;&#x4EF6;&#x5B58;&#x5728;&#x76F4;&#x5230;&#x8D85;&#x65F6;</span>
cup.services.autowait.wait_until_file_exist(dst_path, file_name, max_wait_sec=<span class="hljs-number">10</span>, interval_sec=<span class="hljs-number">2</span>,recursive=<span class="hljs-keyword">False</span>)

<span class="hljs-comment"># &#x7B49;&#x5F85;&#x6B63;&#x5219;&#x5B57;&#x7B26;&#x4E32;&#x5728;&#x6587;&#x4EF6;&#x5B58;&#x5728;&#x76F4;&#x5230;&#x8D85;&#x65F6;,&#x5982;&#x679C;&#x8BFB;&#x53D6;&#x5931;&#x8D25;&#xFF0C;raise IOError</span>
cup.services.autowait.wait_until_reg_str_exist(dst_file_path, reg_str, max_wait_sec=<span class="hljs-number">10</span>,interval_sec=<span class="hljs-number">0.5</span>)[source]

<span class="hljs-comment"># &#x7B49;&#x5F85;&#x7279;&#x5B9A;&#x8DEF;&#x5F84;&#x7684;&#x8FDB;&#x7A0B;&#x4E0D;&#x5B58;&#x5728;&#x76F4;&#x5230;&#x8D85;&#x65F6;</span>
cup.services.autowait.wait_until_process_not_exist(process_path, max_wait_sec=<span class="hljs-number">10</span>,interval_sec=<span class="hljs-number">0.5</span>)[source]
</code></pre>
<h2 id="15-bufferpool-&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;"><a name="15-bufferpool-&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;" class="plugin-anchor" href="#15-bufferpool-&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;"><i class="fa fa-link" aria-hidden="true"></i></a>1.5 BufferPool &#x5185;&#x5B58;&#x7F13;&#x51B2;&#x533A;</h2>
<pre><code class="lang-python"><span class="hljs-comment"># 1. Buffer&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x4EE5;&#x53CA;Bufferpool&#x5185;&#x5B58;&#x7F13;&#x51B2;&#x6C60;</span>
<span class="hljs-comment"># http://cupdoc.iobusy.com/cup.services/#module-cup.services.buffers</span>
<span class="hljs-comment"># &#x7531;&#x4E8E;Python&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x7684;&#x7279;&#x70B9;&#xFF0C;&#x5728;&#x6BD4;&#x5982;&#x7F51;&#x7EDC;&#x901A;&#x4FE1;&#x4EE5;&#x53CA;&#x9891;&#x7E41;&#xFF08;&#x7A0D;&#x5927;&#xFF09;&#x5185;&#x5B58;&#x7684;&#x7533;&#x8BF7;&#x91CA;&#x653E;&#x65F6;&#x5019;&#x4F1A;&#x9000;&#x5316;&#x4E3A;malloc/free&#x3002; &#x5177;&#x4F53;&#x53EF;&#x89C1;&#x4E24;&#x7BC7;&#x6BD4;&#x8F83;&#x597D;&#x7684;&#x89E3;&#x91CA;&#x6587;&#x7AE0;&#xFF1A;</span>
<span class="hljs-comment">#  (a). stackflow&#x7684;&#x5173;&#x4E8E;&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x53EF;&#x4EE5;&#x7528;bytearray</span>
<span class="hljs-comment"># http://stackoverflow.com/questions/9099145/where-are-python-bytearrays-used</span>

<span class="hljs-comment">#  (b). Python&#x7684;&#x5185;&#x5B58;&#x7BA1;&#x7406;</span>

<span class="hljs-comment">#  http://leyafo.logdown.com/posts/159345-python-memory-management</span>

<span class="hljs-comment"># &#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x76F4;&#x63A5;&#x4F7F;&#x7528;str&#x6765;&#x5B58;&#x50A8;&#x6548;&#x7387;&#x4F4E;&#x4E0B;&#xFF0C;&#x4F46;&#x597D;&#x6D88;&#x606F;&#x662F;python&#x539F;&#x751F;&#x63D0;&#x4F9B;&#x4E86;bytearray&#x8FD9;&#x6837;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x3002;&#x5229;&#x7528;&#x5979;mutable&#x53EF;&#x53D8;&#x7684;&#x7279;&#x6027;&#x505A;&#x6210;Buffer&#xFF0C;&#x8FDB;&#x4E00;&#x6B65;&#x7EC4;&#x6210;Bufferpool&#x5185;&#x5B58;&#x7F13;&#x5B58;&#x6C60;&#xFF0C;&#x975E;&#x5E38;&#x9002;&#x914D;&#x9891;&#x7E41;&#x7533;&#x8BF7;&#x91CA;&#x653E;&#x8F83;&#x5927;&#x5185;&#x5B58;&#x7684;&#x573A;&#x666F;&#x3002;</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> sys
<span class="hljs-keyword">import</span> logging

<span class="hljs-keyword">from</span> cup.services <span class="hljs-keyword">import</span> buffers
<span class="hljs-keyword">from</span> cup <span class="hljs-keyword">import</span> unittest

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CTestServiceBuffer</span><span class="hljs-params">(unittest.CUTCase)</span>:</span>
    <span class="hljs-string">&quot;&quot;&quot;
    service buffer
    &quot;&quot;&quot;</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
        super(self.__class__, self).__init__()
        self._buffpool = buffers.BufferPool(
            buffers.MEDIUM_BLOCK_SIZE,
            <span class="hljs-number">102400</span>,
        )

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_run</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-string">&quot;&quot;&quot;test_run&quot;&quot;&quot;</span>
        ret, buff = self._buffpool.allocate(<span class="hljs-number">102401</span>)  <span class="hljs-comment"># &#x56DE;&#x8FD4;&#x7684;&#x662F;Buffer&#x6570;&#x636E;&#x7ED3;&#x6784;</span>
        unittest.assert_eq(ret, <span class="hljs-keyword">False</span>)

        ret, buff = self._buffpool.allocate(<span class="hljs-number">10</span>)
        unittest.assert_eq(ret, <span class="hljs-keyword">True</span>)
        <span class="hljs-comment"># pylint: disable=W0212</span>
        unittest.assert_eq(self._buffpool._used_num, <span class="hljs-number">10</span>)
        unittest.assert_eq(self._buffpool._free_num, <span class="hljs-number">102390</span>)
        ret = buff.set(<span class="hljs-string">&apos;a&apos;</span> * <span class="hljs-number">10</span> * buffers.MEDIUM_BLOCK_SIZE)  <span class="hljs-comment"># Buffer&#x6570;&#x636E;&#x7ED3;&#x6784;&#x652F;&#x6301;set&#x8BED;&#x4E49;</span>
        unittest.assert_eq(ret[<span class="hljs-number">0</span>], <span class="hljs-keyword">True</span>)
        ret = buff.set(<span class="hljs-string">&apos;a&apos;</span> * (<span class="hljs-number">10</span> * buffers.MEDIUM_BLOCK_SIZE + <span class="hljs-number">1</span>))
        unittest.assert_ne(ret[<span class="hljs-number">0</span>], <span class="hljs-keyword">True</span>)
        self._buffpool.deallocate(buff)     <span class="hljs-comment"># &#x5F52;&#x8FD8;buffer&#x5230;&#x7EBF;&#x7A0B;&#x6C60;</span>
        <span class="hljs-comment"># pylint: disable=W0212</span>
        unittest.assert_eq(self._buffpool._used_num, <span class="hljs-number">0</span>)
        unittest.assert_eq(self._buffpool._free_num, <span class="hljs-number">102400</span>)
        unittest.assert_eq(len(self._buffpool._free_list), <span class="hljs-number">102400</span>)
        unittest.assert_eq(len(self._buffpool._used_dict), <span class="hljs-number">0</span>)
</code></pre>
<h2 id="16-generator"><a name="16-generator" class="plugin-anchor" href="#16-generator"><i class="fa fa-link" aria-hidden="true"></i></a>1.6 Generator</h2>
<p>a. &#x7528;&#x6765;&#x751F;&#x6210;&#x5404;&#x7C7B;&#x552F;&#x4E00;&#x6570;&#xFF0C;&#x5B57;&#x7B26;&#x96C6;&#xFF0C;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#x7684;&#x81EA;&#x589E;uint&#x7684;&#x7C7B;&#x3002; &#x76EE;&#x524D;&#x751F;&#x6210;&#x51FD;&#x6570;&#x8F83;&#x5C11;&#xFF0C; &#x6B22;&#x8FCE;&#x5927;&#x5BB6;&#x8D21;&#x732E;ci. Singleton&#x7C7B;&#x3002;</p>
<pre><code class="lang-python"><span class="hljs-comment"># &#x521D;&#x59CB;&#x5316;&#x9700;&#x8981;&#x4F20;&#x5165;&#x4E00;&#x4E2A;&#x7528;&#x6765;&#x751F;&#x6210;&#x5B57;&#x7B26;&#x96C6;&#x7684;string.</span>
<span class="hljs-comment"># &#x521D;&#x59CB;&#x5316;&#x51FD;&#x6570;:</span>
__init__(self, str_prefix=get_local_hostname()) <span class="hljs-comment"># &#x9ED8;&#x8BA4;&#x4F20;&#x5165;&#x5F53;&#x524D;&#x81EA;&#x5DF1;&#x7684;hostname</span>

<span class="hljs-comment"># &#x6210;&#x5458;&#x51FD;&#x6570;:</span>
get_uniqname()   <span class="hljs-comment"># &#x83B7;&#x5F97;&#x4E00;&#x4E2A;&#x4EE5;&#x4F20;&#x5165;&#x7684;&#x521D;&#x59CB;&#x5316;string&#x4E3A;base, &#x52A0;&#x4E0A;pid, threadid&#x7B49;&#x7EC4;&#x5408;&#x7684;host&#x7EA7;&#x522B;&#x7684; unique</span>
get_next_uniq_num() <span class="hljs-comment"># &#x83B7;&#x5F97;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x552F;&#x4E00;&#x7684;&#x81EA;&#x589E;&#x975E;&#x8D1F;&#x6574;&#x6570;&#x3002;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;.</span>
</code></pre>
<p>b. CycleIDGenerator 128bit&#x5FAA;&#x73AF;id&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#x81EA;&#x589E;ID&#x751F;&#x6210;&#x5668;</p>
<pre><code class="lang-python">next_id() <span class="hljs-comment"># &#x652F;&#x6301;&#x83B7;&#x53D6;&#x5FAA;&#x73AF;&#x4E14;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#x7684;next id</span>
</code></pre>
<h2 id="17-serializer-meta&#x6301;&#x4E45;&#x5316;"><a name="17-serializer-meta&#x6301;&#x4E45;&#x5316;" class="plugin-anchor" href="#17-serializer-meta&#x6301;&#x4E45;&#x5316;"><i class="fa fa-link" aria-hidden="true"></i></a>1.7 Serializer Meta&#x6301;&#x4E45;&#x5316;</h2>
<p>&#x793A;&#x4F8B;&#x5236;&#x4F5C;&#x4E2D;</p>
<h2 id="18-heartbeat-&#x5FC3;&#x8DF3;&#x670D;&#x52A1;"><a name="18-heartbeat-&#x5FC3;&#x8DF3;&#x670D;&#x52A1;" class="plugin-anchor" href="#18-heartbeat-&#x5FC3;&#x8DF3;&#x670D;&#x52A1;"><i class="fa fa-link" aria-hidden="true"></i></a>1.8 HeartBeat &#x5FC3;&#x8DF3;&#x670D;&#x52A1;</h2>
<p>&#x793A;&#x4F8B;&#x5236;&#x4F5C;&#x4E2D;</p>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="CommonUserSenario.html" class="navigation navigation-prev " aria-label="Previous page: 基础功能">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="GeneralService.html" class="navigation navigation-next " aria-label="Next page: 快速构建PythonService">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"通用服务","level":"1.2.2","depth":2,"next":{"title":"快速构建PythonService","level":"1.2.3","depth":2,"path":"senarios/GeneralService.md","ref":"senarios/GeneralService.md","articles":[]},"previous":{"title":"基础功能","level":"1.2.1","depth":2,"path":"senarios/CommonUserSenario.md","ref":"senarios/CommonUserSenario.md","articles":[]},"dir":"ltr"},"config":{"plugins":["-sharing","splitter","anchors","sharing-plus","favicon","insert-logo","chinese-video","github-buttons"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"splitter":{},"search":{},"sharing-plus":{"qq":false,"all":["facebook","google","twitter","instapaper","linkedin","pocket","stumbleupon"],"douban":false,"facebook":true,"weibo":false,"instapaper":false,"whatsapp":false,"hatenaBookmark":false,"twitter":true,"messenger":false,"line":false,"vk":false,"pocket":true,"google":false,"viber":false,"stumbleupon":false,"qzone":false,"linkedin":false},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"fontsettings":{"theme":"white","family":"sans","size":2},"highlight":{},"anchor-navigation-ex":{"showLevel":false,"mode":"float","pageTop":{"showLevelIcon":true,"level1Icon":"fa fa-hand-o-right","level2Icon":"fa fa-hand-o-right","level3Icon":"fa fa-hand-o-right"}},"favicon":{"shortcut":"./images/cup.logo.jpg","bookmark":"./images/cup.logo.jpg","appleTouch":"./images/cup.logo.jpg"},"github-buttons":{"repo":"baidu/CUP","types":["star","watch","fork"],"size":"large"},"chinese-video":{},"sharing":{"qq":false,"all":["google","facebook","weibo","twitter","qq","qzone","linkedin","pocket"],"douban":false,"facebook":false,"weibo":false,"instapaper":false,"whatsapp":false,"hatenaBookmark":false,"twitter":false,"messenger":false,"line":false,"vk":false,"pocket":false,"google":false,"viber":false,"stumbleupon":false,"qzone":false,"linkedin":false},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false},"anchors":{},"insert-logo":{"style":"background: none;","url":"http://cup.iobusy.com/cup.logo.png"}},"theme":"default","author":"Guannan Ma","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"Cup Documentation","language":"zh-hans","links":{"sidebar":{"Github Website":"https://github.com/baidu/CUP"}},"gitbook":"*","description":"Cup Documentation which you may refer to"},"file":{"path":"senarios/CommonService.md","mtime":"2023-01-21T08:53:42.477Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2023-01-30T11:36:43.723Z"},"basePath":"..","book":{"language":"zh-hans"}});
        });
    </script>
</div>

        
    <script src="../../gitbook/gitbook.js"></script>
    <script src="../../gitbook/theme.js"></script>
    
        
        <script src="../../gitbook/gitbook-plugin-splitter/splitter.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-sharing-plus/buttons.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-insert-logo/plugin.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-github-buttons/plugin.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

